package com.yanggu.scala.chapater09.implicitVal

//小结
//1. 当在程序中，同时有隐式值、默认值、传值
//2. 编译器的优先级为 传值 > 隐式值 > 默认值
//3. 在隐式值匹配时，不能有二义性
//4. 如果三个（隐式值、默认值、传值）一个都没有，就会报错

//隐式参数使用的常见问题：
//      1）当函数没有柯里化时，implicit关键字会作用于函数列表中的的所有参数。
//
//      2）隐式参数使用时要么全部不指定，要么全不指定，不能只指定部分。
//      3）同类型的隐式值只能在作用域内出现一次，即不能在同一个作用域中定义多个相同类型的隐式值。
//
//      4）在指定隐式参数时，implicit 关键字只能出现在参数开头。
//
//      5）如果想要实现参数的部分隐式参数，只能使用函数的柯里化，
//
//          如要实现这种形式的函数，def test(x:Int, implicit  y: Double)的形式，必须使用柯里化实现：def test(x: Int)(implicit y: Double).
//
//       6) 柯里化的函数， implicit 关键字只能作用于最后一个参数。否则，不合法。
//
//       7）implicit 关键字在隐式参数中只能出现一次，柯里化的函数也不例外！
object ImplicitValDemo02 {

  def main(args: Array[String]): Unit = {
    // 隐式变量（值）
    //implicit val name2: String = "Scala"
    implicit val name1: String = "World"

    //隐式参数
    def hello(implicit content: String): Unit = {
      println("Hello " + content)
    }

    //调用hello, 打印Hello World
    hello

    //当同时有隐式值和默认值，隐式优先级高
    def hello2(implicit content: String = "jack"): Unit = {
      println("Hello2 " + content)
    }

    //调用hello2, 打印Hello2 World
    hello2

    //当一个隐式参数匹配不到隐式值，仍然会使用默认值
    def hello3(implicit content: Int = 123): Unit = {
      println("Hello3 " + content)
    }

    //调用hello3, 打印Hello3 123
    hello3

    //当没有隐式值，没有默认值，又没有传值，就会报错
    def hello4(implicit content: Double): Unit = {
      println("Hello4 " + content)
    }

    //编译器直接报错, No implicits found for parameter content
    //hello4
  }

}
